import csv
import io
from datetime import datetime
from django.http import HttpResponse
from openpyxl import Workbook
from openpyxl.styles import Font, Alignment, PatternFill
from openpyxl.utils import get_column_letter
import xlsxwriter


class SurveyExporter:
    """勘查记录导出工具类"""
    
    def __init__(self, queryset, user):
        self.queryset = queryset
        self.user = user
    
    def export_csv(self):
        """导出为CSV格式"""
        response = HttpResponse(content_type='text/csv; charset=utf-8')
        response['Content-Disposition'] = f'attachment; filename="survey_records_{datetime.now().strftime("%Y%m%d_%H%M%S")}.csv"'
        
        # 添加BOM以支持中文显示
        response.write('\ufeff')
        
        writer = csv.writer(response)
        
        # 写入标题行
        headers = [
            '记录ID', '地点名称', '详细地址', '纬度', '经度', 
            '朝向', '备注', '勘查日期', '创建时间', '更新时间', 
            '图片数量', '图片列表'
        ]
        writer.writerow(headers)
        
        # 写入数据行
        for record in self.queryset:
            images = record.images.all()
            image_count = images.count()
            image_list = '; '.join([img.orientation or f'图片{i+1}' for i, img in enumerate(images)])
            
            row = [
                record.id,
                record.location_name or '',
                record.address or '',
                str(record.latitude) if record.latitude else '',
                str(record.longitude) if record.longitude else '',
                record.orientation or '',
                record.notes or '',
                record.survey_date.strftime('%Y-%m-%d %H:%M:%S') if record.survey_date else '',
                record.created_at.strftime('%Y-%m-%d %H:%M:%S'),
                record.updated_at.strftime('%Y-%m-%d %H:%M:%S'),
                image_count,
                image_list
            ]
            writer.writerow(row)
        
        return response
    
    def export_excel(self):
        """导出为Excel格式（使用openpyxl）"""
        response = HttpResponse(
            content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )
        response['Content-Disposition'] = f'attachment; filename="survey_records_{datetime.now().strftime("%Y%m%d_%H%M%S")}.xlsx"'
        
        workbook = Workbook()
        worksheet = workbook.active
        worksheet.title = "勘查记录"
        
        # 设置标题样式
        title_font = Font(bold=True, color="FFFFFF")
        title_fill = PatternFill(start_color="366092", end_color="366092", fill_type="solid")
        title_alignment = Alignment(horizontal="center", vertical="center")
        
        # 写入标题行
        headers = [
            '记录ID', '地点名称', '详细地址', '纬度', '经度', 
            '朝向', '备注', '勘查日期', '创建时间', '更新时间', 
            '图片数量', '图片列表'
        ]
        
        for col, header in enumerate(headers, 1):
            cell = worksheet.cell(row=1, column=col, value=header)
            cell.font = title_font
            cell.fill = title_fill
            cell.alignment = title_alignment
        
        # 写入数据行
        for row, record in enumerate(self.queryset, 2):
            images = record.images.all()
            image_count = images.count()
            image_list = '; '.join([img.orientation or f'图片{i+1}' for i, img in enumerate(images)])
            
            data = [
                record.id,
                record.location_name or '',
                record.address or '',
                str(record.latitude) if record.latitude else '',
                str(record.longitude) if record.longitude else '',
                record.orientation or '',
                record.notes or '',
                record.survey_date.strftime('%Y-%m-%d %H:%M:%S') if record.survey_date else '',
                record.created_at.strftime('%Y-%m-%d %H:%M:%S'),
                record.updated_at.strftime('%Y-%m-%d %H:%M:%S'),
                image_count,
                image_list
            ]
            
            for col, value in enumerate(data, 1):
                worksheet.cell(row=row, column=col, value=value)
        
        # 自动调整列宽
        for col in range(1, len(headers) + 1):
            column_letter = get_column_letter(col)
            max_length = 0
            for row in range(1, worksheet.max_row + 1):
                cell_value = str(worksheet[f'{column_letter}{row}'].value or '')
                max_length = max(max_length, len(cell_value))
            
            # 设置最大宽度限制
            adjusted_width = min(max_length + 2, 50)
            worksheet.column_dimensions[column_letter].width = adjusted_width
        
        # 冻结首行
        worksheet.freeze_panes = 'A2'
        
        # 保存到内存
        excel_file = io.BytesIO()
        workbook.save(excel_file)
        excel_file.seek(0)
        
        response.write(excel_file.getvalue())
        return response
    
    def export_excel_advanced(self):
        """导出为Excel格式（使用xlsxwriter，支持更多格式）"""
        response = HttpResponse(
            content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )
        response['Content-Disposition'] = f'attachment; filename="survey_records_advanced_{datetime.now().strftime("%Y%m%d_%H%M%S")}.xlsx"'
        
        # 创建内存文件
        output = io.BytesIO()
        workbook = xlsxwriter.Workbook(output, {'in_memory': True})
        
        # 创建工作表
        worksheet = workbook.add_worksheet('勘查记录')
        stats_worksheet = workbook.add_worksheet('统计分析')
        
        # 定义格式
        header_format = workbook.add_format({
            'bold': True,
            'font_color': 'white',
            'bg_color': '#366092',
            'align': 'center',
            'valign': 'vcenter',
            'border': 1
        })
        
        data_format = workbook.add_format({
            'align': 'left',
            'valign': 'top',
            'border': 1,
            'text_wrap': True
        })
        
        date_format = workbook.add_format({
            'num_format': 'yyyy-mm-dd hh:mm:ss',
            'align': 'center',
            'border': 1
        })
        
        number_format = workbook.add_format({
            'align': 'center',
            'border': 1
        })
        
        # 写入标题行
        headers = [
            '记录ID', '地点名称', '详细地址', '纬度', '经度', 
            '朝向', '备注', '勘查日期', '创建时间', '更新时间', 
            '图片数量', '图片列表'
        ]
        
        for col, header in enumerate(headers):
            worksheet.write(0, col, header, header_format)
        
        # 写入数据
        for row, record in enumerate(self.queryset, 1):
            images = record.images.all()
            image_count = images.count()
            image_list = '; '.join([img.orientation or f'图片{i+1}' for i, img in enumerate(images)])
            
            worksheet.write(row, 0, record.id, number_format)
            worksheet.write(row, 1, record.location_name or '', data_format)
            worksheet.write(row, 2, record.address or '', data_format)
            worksheet.write(row, 3, str(record.latitude) if record.latitude else '', data_format)
            worksheet.write(row, 4, str(record.longitude) if record.longitude else '', data_format)
            worksheet.write(row, 5, record.orientation or '', data_format)
            worksheet.write(row, 6, record.notes or '', data_format)
            
            if record.survey_date:
                worksheet.write_datetime(row, 7, record.survey_date, date_format)
            else:
                worksheet.write(row, 7, '', data_format)
                
            worksheet.write_datetime(row, 8, record.created_at, date_format)
            worksheet.write_datetime(row, 9, record.updated_at, date_format)
            worksheet.write(row, 10, image_count, number_format)
            worksheet.write(row, 11, image_list, data_format)
        
        # 设置列宽
        column_widths = [10, 20, 30, 15, 15, 15, 30, 20, 20, 20, 10, 40]
        for col, width in enumerate(column_widths):
            worksheet.set_column(col, col, width)
        
        # 冻结首行
        worksheet.freeze_panes(1, 0)
        
        # 添加统计分析工作表
        self._add_statistics_sheet(stats_worksheet, workbook)
        
        workbook.close()
        output.seek(0)
        
        response.write(output.getvalue())
        return response
    
    def _add_statistics_sheet(self, worksheet, workbook):
        """添加统计分析工作表"""
        # 格式定义
        title_format = workbook.add_format({
            'bold': True,
            'font_size': 16,
            'align': 'center',
            'bg_color': '#D9E1F2'
        })
        
        header_format = workbook.add_format({
            'bold': True,
            'bg_color': '#B4C6E7',
            'align': 'center',
            'border': 1
        })
        
        data_format = workbook.add_format({
            'align': 'center',
            'border': 1
        })
        
        # 标题
        worksheet.merge_range('A1:D1', f'勘查记录统计分析 - {self.user.username}', title_format)
        
        # 基础统计
        row = 3
        worksheet.write(row, 0, '基础统计', header_format)
        worksheet.write(row + 1, 0, '总记录数', data_format)
        worksheet.write(row + 1, 1, self.queryset.count(), data_format)
        
        # 按朝向统计
        orientation_stats = {}
        for record in self.queryset:
            orientation = record.orientation or '未指定'
            orientation_stats[orientation] = orientation_stats.get(orientation, 0) + 1
        
        row += 4
        worksheet.write(row, 0, '朝向分布', header_format)
        worksheet.write(row, 1, '记录数', header_format)
        
        for i, (orientation, count) in enumerate(sorted(orientation_stats.items(), key=lambda x: x[1], reverse=True)):
            worksheet.write(row + 1 + i, 0, orientation, data_format)
            worksheet.write(row + 1 + i, 1, count, data_format)
        
        # 设置列宽
        worksheet.set_column('A:A', 20)
        worksheet.set_column('B:B', 15)
        worksheet.set_column('C:C', 15)
        worksheet.set_column('D:D', 15)


class FavoriteLocationExporter:
    """常用地点导出工具类"""
    
    def __init__(self, queryset, user):
        self.queryset = queryset
        self.user = user
    
    def export_csv(self):
        """导出为CSV格式"""
        response = HttpResponse(content_type='text/csv; charset=utf-8')
        response['Content-Disposition'] = f'attachment; filename="favorite_locations_{datetime.now().strftime("%Y%m%d_%H%M%S")}.csv"'
        
        # 添加BOM以支持中文显示
        response.write('\ufeff')
        
        writer = csv.writer(response)
        
        # 写入标题行
        headers = ['ID', '地点名称', '详细地址', '纬度', '经度', '创建时间']
        writer.writerow(headers)
        
        # 写入数据行
        for location in self.queryset:
            row = [
                location.id,
                location.name or '',
                location.address or '',
                str(location.latitude) if location.latitude else '',
                str(location.longitude) if location.longitude else '',
                location.created_at.strftime('%Y-%m-%d %H:%M:%S')
            ]
            writer.writerow(row)
        
        return response
    
    def export_excel(self):
        """导出为Excel格式"""
        response = HttpResponse(
            content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )
        response['Content-Disposition'] = f'attachment; filename="favorite_locations_{datetime.now().strftime("%Y%m%d_%H%M%S")}.xlsx"'
        
        workbook = Workbook()
        worksheet = workbook.active
        worksheet.title = "常用地点"
        
        # 设置标题样式
        title_font = Font(bold=True, color="FFFFFF")
        title_fill = PatternFill(start_color="366092", end_color="366092", fill_type="solid")
        title_alignment = Alignment(horizontal="center", vertical="center")
        
        # 写入标题行
        headers = ['ID', '地点名称', '详细地址', '纬度', '经度', '创建时间']
        
        for col, header in enumerate(headers, 1):
            cell = worksheet.cell(row=1, column=col, value=header)
            cell.font = title_font
            cell.fill = title_fill
            cell.alignment = title_alignment
        
        # 写入数据行
        for row, location in enumerate(self.queryset, 2):
            data = [
                location.id,
                location.name or '',
                location.address or '',
                str(location.latitude) if location.latitude else '',
                str(location.longitude) if location.longitude else '',
                location.created_at.strftime('%Y-%m-%d %H:%M:%S')
            ]
            
            for col, value in enumerate(data, 1):
                worksheet.cell(row=row, column=col, value=value)
        
        # 自动调整列宽
        for col in range(1, len(headers) + 1):
            column_letter = get_column_letter(col)
            max_length = 0
            for row in range(1, worksheet.max_row + 1):
                cell_value = str(worksheet[f'{column_letter}{row}'].value or '')
                max_length = max(max_length, len(cell_value))
            
            adjusted_width = min(max_length + 2, 50)
            worksheet.column_dimensions[column_letter].width = adjusted_width
        
        # 冻结首行
        worksheet.freeze_panes = 'A2'
        
        # 保存到内存
        excel_file = io.BytesIO()
        workbook.save(excel_file)
        excel_file.seek(0)
        
        response.write(excel_file.getvalue())
        return response